package durst.action;

import java.sql.SQLException;
import java.util.Calendar;
import java.util.Random;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sourceforge.stripes.action.ActionBeanContext;

import org.apache.log4j.Logger;
import org.springframework.security.util.EncryptionUtils;

import com.j256.ormlite.dao.Dao;

import durst.data.Account;
import durst.data.CookieToAccount;
import durst.data.dao.DaoFactory;
import durst.data.dao.impl.CookieToAccountDao;
import durst.utils.ConfigParser;

public class CalendarContext extends ActionBeanContext {
	private static Random random = new Random(System.currentTimeMillis());
	private final static int MAX = 900000000;
	private final static int MIN = 100000000;
	private final static String KEY = ConfigParser.getProp("durst.cookie.key");

	public Cookie getCookie(String name) {
		for (Cookie c : getRequest().getCookies())
			if (c.getName().equals(name))
				return c;

		return null;
	}

	public void addCookie(Cookie c) {
		getResponse().addCookie(c);
	}

	public Object getAttribute(String name) {
		return getRequest().getSession().getAttribute(name);
	}

	public void setAttribute(String name, Object obj) {
		getRequest().getSession().setAttribute(name, obj);
	}

	public void setAccount(Account acc) {
		try {
			if (acc != null) {
				int rand;
				Dao<CookieToAccount, Integer> dao = DaoFactory.getInstance()
						.createDao(CookieToAccount.class);

				do {
					rand = random.nextInt(MAX) + MIN;
				} while (dao.queryForId(rand) != null);

				Calendar now = Calendar.getInstance();
				now.add(Calendar.DATE, 7);
				dao.create(new CookieToAccount(rand, acc, now.getTime()));

				StringBuilder builder = new StringBuilder(
						Integer.toString(rand));
				builder.append(";").append(acc.getId());
				Cookie cookie = new Cookie("account", EncryptionUtils.encrypt(
						KEY, builder.toString()));
				cookie.setMaxAge(60 * 60 * 24 * 7);

				addCookie(cookie);
				setAttribute("account", acc);
			} else {
				addCookie(new Cookie("account", null));
				setAttribute("account", null);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public Account getAccount() {
		return getAccount(getRequest(), getResponse());
	}

	@SuppressWarnings("unchecked")
	public static Account getAccount(HttpServletRequest request,
			HttpServletResponse response) {
		if (request.getSession().getAttribute("account") != null) {
			return (Account) request.getSession().getAttribute("account");
		}

		if (request.getCookies() != null) {
			for (Cookie c : request.getCookies()) {
				if (c.getName().equals("account") && c.getValue() != null
						&& !c.getValue().isEmpty()) {
					String decrypted = EncryptionUtils.decrypt(KEY,
							c.getValue());

					Account res;
					try {
						res = ((CookieToAccountDao<CookieToAccount, Integer>) DaoFactory
								.getInstance().createDao(CookieToAccount.class))
								.findById(
										Integer.parseInt(decrypted.split(";")[0]),
										Calendar.getInstance().getTime());
						if (res != null
								&& res.getId() == Integer.parseInt(decrypted
										.split(";")[1])) {
							request.getSession().setAttribute("account", res);
							return res;
						}
					} catch (ArrayIndexOutOfBoundsException err) {
					} catch (NumberFormatException e) {
					} catch (SQLException e) {
						Logger.getLogger(CalendarContext.class).error(
								"SQL Exception!");
					}
					response.addCookie(new Cookie("account", null));
				}
			}
		}

		return null;
	}
}
